home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / dsp / wefax.arc / WEFDEMOD.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-02-17  |  14.5 KB  |  655 lines

  1. ;             AMSAT/TAPR DSP WEFAX demodulator
  2. ;           Sample rate should be set to 10000 samples/sec. 
  3. ;    Code by Bob McGwier N4HY.  Copyright 1988, ALL RIGHTS RESERVED!
  4. ;
  5. ; Needs: post frequency synthesis filtering and adaptive equalization
  6. ;        to achieve "perfection" :-)
  7.      org 0
  8.      b go
  9.      org 0FF0H
  10.      dw 3932  ; 2400Hz at 10000 samples/sec
  11. ;
  12. ;      Okay Jose' set up equates for data memory etc.
  13. ;
  14.         org 10H  ;  code should begin at memory address 16 cause David
  15.            ;  does something strange with locations 0-15.  Does
  16.            ;  he in fact document this?  Is it a TMS32010 feature?
  17.     
  18. sine:   equ 0    ;  will store sine values from tone
  19. one:    equ 1      ;  guess what goes here duhhhhh!
  20. freq:   equ 2    ;  PLL frequency stored here
  21. phase:  equ 3    ;  PLL phase stored here
  22. maskl:  equ 4    ;  mask for fine or low order bits of phase
  23. mask:   equ 5    ;  mask for doing modulo 16384 arithmetic with phase
  24. sinx:   equ 6    ;  used to store coarse sine value (high order bits)
  25. cosx:   equ 7    ;  as above for cosine
  26. mone:   equ 8    ;   minus one stored here
  27. wkph:   equ 9    ;  different phases (PLL, remodulator tone etc) are stored hr
  28.                  ;  for frequency synthesis
  29. masko:  equ 10   ;  mask for converting on board PCM to DAC format
  30. mps:    equ 11   ;  multiplier for quadrant determination for sine
  31. mpc:    equ 12   ;  multiplier for quadrant determination for cosine
  32. siny:   equ 13   ;  fine correction value for use in SIN(X+Y) = sinx*cosy+
  33. cosy:   equ 14   ;          cosx*siny
  34. cosine: equ 15   ;  cosine is also needed for Q arm in Costas loop
  35. coph:   equ 16   ;  working number holder
  36. modem:  equ 17   ;  Used to choose between complex tone for arms and real tone
  37.                  ;  in the modulator as explained below
  38. contr:    equ 18
  39.  
  40. freqo:  equ 20   ;  freqo is assigned one of the values above for remod
  41. phaseo: equ 71      ;  phaseo is the phase of the remodulator output. phase is
  42.            ;  as continuous as DSP will allow on this board
  43. xn0:    equ 21   ;  place  for storing all the values for the "I" or data arm
  44. xn1:    equ 22
  45. xn2:    equ 23
  46. xn3:    equ 24
  47. xn4:    equ 25
  48. xn5:    equ 26
  49. xn6:    equ 27
  50. xn7:    equ 28
  51. xn8:    equ 29
  52. xn9:    equ 30
  53. xn10:   equ 31
  54. xn11:   equ 32
  55. xn12:   equ 33
  56. xn13:   equ 34
  57. xn14:   equ 35
  58. xn15:   equ 36
  59. xn16:   equ 37
  60. xn17:   equ 38
  61. xn18:   equ 39
  62. xn19:   equ 40
  63. xn20:   equ 41
  64. xn21:   equ 42
  65. xn22:   equ 43
  66. xn23:   equ 44
  67. yn0:    equ 45  ; storage for values in "Q" or phase error arm.
  68. yn1:    equ 46
  69. yn2:    equ 47
  70. yn3:    equ 48
  71. yn4:    equ 49
  72. yn5:    equ 50
  73. yn6:    equ 51
  74. yn7:    equ 52
  75. yn8:    equ 53
  76. yn9:    equ 54
  77. yn10:   equ 55
  78. yn11:   equ 56
  79. yn12:   equ 57
  80. yn13:   equ 58
  81. yn14:   equ 59
  82. yn15:   equ 60
  83. yn16:   equ 61
  84. yn17:   equ 62
  85. yn18:   equ 63
  86. yn19:   equ 64
  87. yn20:   equ 65
  88. yn21:   equ 66
  89. yn22:   equ 67
  90. yn23:   equ 68
  91. c0:     equ 69  ; Phase error
  92. maskf:  equ 70  ; frequency mask so that frequency doesn't try and leave
  93.                 ; proper range
  94. tester: equ 72  ;  remodulator output   -300 to 300 millivolts on DAC's
  95. data:   equ 73
  96. h10:    equ 74
  97. h11:    equ 75
  98. armfilt: dw 6861
  99.      dw 9601
  100. sintbl: dw      0  ; coarse sine table in steps of PI/64 radians to PI/2
  101.        dw    804
  102.        dw   1607
  103.        dw   2410
  104.        dw   3211
  105.        dw   4011
  106.        dw   4807
  107.        dw   5601
  108.        dw   6392
  109.        dw   7179
  110.        dw   7961
  111.        dw   8739
  112.        dw   9511
  113.        dw  10278
  114.        dw  11038
  115.        dw  11792
  116.        dw  12539
  117.        dw  13278
  118.        dw  14009
  119.        dw  14732
  120.        dw  15446
  121.        dw  16150
  122.        dw  16845
  123.        dw  17530
  124.        dw  18204
  125.        dw  18867
  126.        dw  19519
  127.        dw  20159
  128.        dw  20787
  129.        dw  21402
  130.        dw  22004
  131.        dw  22594
  132.        dw  23169
  133.        dw  23731
  134.        dw  24278
  135.        dw  24811
  136.        dw  25329
  137.        dw  25831
  138.        dw  26318
  139.        dw  26789
  140.        dw  27244
  141.        dw  27683
  142.        dw  28105
  143.        dw  28510
  144.        dw  28897
  145.        dw  29268
  146.        dw  29621
  147.        dw  29955
  148.        dw  30272
  149.        dw  30571
  150.        dw  30851
  151.        dw  31113
  152.        dw  31356
  153.        dw  31580
  154.        dw  31785
  155.        dw  31970
  156.        dw  32137
  157.        dw  32284
  158.        dw  32412
  159.        dw  32520
  160.        dw  32609
  161.        dw  32678
  162.        dw  32727
  163.        dw  32757
  164.        dw  32767  ; PI/2
  165. fines: dw      0  ; fine sine table  in steps of PI/(64*64) radians to PI/64
  166.        dw     12
  167.        dw     25
  168.        dw     37
  169.        dw     50
  170.        dw     62
  171.        dw     75
  172.        dw     87
  173.        dw    100
  174.        dw    113
  175.        dw    125
  176.        dw    138
  177.        dw    150
  178.        dw    163
  179.        dw    175
  180.        dw    188
  181.        dw    201
  182.        dw    213
  183.        dw    226
  184.        dw    238
  185.        dw    251
  186.        dw    263
  187.        dw    276
  188.        dw    289
  189.        dw    301
  190.        dw    314
  191.        dw    326
  192.        dw    339
  193.        dw    351
  194.        dw    364
  195.        dw    376
  196.        dw    389
  197.        dw    402
  198.        dw    414
  199.        dw    427
  200.        dw    439
  201.        dw    452
  202.        dw    464
  203.        dw    477
  204.        dw    490
  205.        dw    502
  206.        dw    515
  207.        dw    527
  208.        dw    540
  209.        dw    552
  210.        dw    565
  211.        dw    578
  212.        dw    590
  213.        dw    603
  214.        dw    615
  215.        dw    628
  216.        dw    640
  217.        dw    653
  218.        dw    665
  219.        dw    678
  220.        dw    691
  221.        dw    703
  222.        dw    716
  223.        dw    728
  224.        dw    741
  225.        dw    753
  226.        dw    766
  227.        dw    779
  228.        dw    791
  229. finec: dw   32767  ;ditto to above for fine sine
  230.        dw   32766
  231.        dw   32766
  232.        dw   32766
  233.        dw   32766
  234.        dw   32766
  235.        dw   32766
  236.        dw   32766
  237.        dw   32766
  238.        dw   32766
  239.        dw   32766
  240.        dw   32766
  241.        dw   32766
  242.        dw   32766
  243.        dw   32766
  244.        dw   32766
  245.        dw   32766
  246.        dw   32766
  247.        dw   32766
  248.        dw   32766
  249.        dw   32766
  250.        dw   32765
  251.        dw   32765
  252.        dw   32765
  253.        dw   32765
  254.        dw   32765
  255.        dw   32765
  256.        dw   32765
  257.        dw   32765
  258.        dw   32764
  259.        dw   32764
  260.        dw   32764
  261.        dw   32764
  262.        dw   32764
  263.        dw   32764
  264.        dw   32764
  265.        dw   32763
  266.        dw   32763
  267.        dw   32763
  268.        dw   32763
  269.        dw   32763
  270.        dw   32762
  271.        dw   32762
  272.        dw   32762
  273.        dw   32762
  274.        dw   32762
  275.        dw   32761
  276.        dw   32761
  277.        dw   32761
  278.        dw   32761
  279.        dw   32760
  280.        dw   32760
  281.        dw   32760
  282.        dw   32760
  283.        dw   32759
  284.        dw   32759
  285.        dw   32759
  286.        dw   32759
  287.        dw   32758
  288.        dw   32758
  289.        dw   32758
  290.        dw   32758
  291.        dw   32757
  292.        dw   32757
  293. go:  ldpk 0         ; make sure that we are pointing to 0 data page
  294.      lack one   ; make and store one
  295.      sacl one
  296.      lac one,11  ; make and store DAC converter mask
  297.      sacl masko
  298.      lac one,13   ; make and store frequency mask
  299.      sub one
  300.      sacl maskf
  301.      zac
  302.      sub one
  303.      sacl mone  ; make and store minus one
  304.      lac one,14
  305.      sub one
  306.      sacl mask  ; make and store mask for modulo 16384 phase arithmetic
  307.      lac one,6
  308.      sub one
  309.      sacl maskl ; make and store fine part of address mask;
  310.      zac
  311.      sacl phase
  312.      lac one,8     ; make and store frequency address in memory
  313.      sub one
  314.      sacl freq
  315.      lac freq,4
  316.      tblr freq       ; read PLL initial frequency
  317.      larp 0
  318.      lark ar0,7
  319.      lack armfilt
  320.      tblr h10
  321.      add one
  322.      tblr h11
  323. ;  Okay the BS is over lets get to work !     
  324.      
  325. wait: bioz fire    ; is it time for a new sample     
  326.       b wait       ; nope go wait in the corner
  327. fire: in xn0,pa3   ; get a new sample here
  328.                ; as the following routines have a variable length
  329.      lac xn0,4
  330.      sub one,15   ; Change ADC format to two's complement
  331.      sacl xn0
  332.      banz ntyt
  333.      out data,pa7
  334.      lac contr
  335.      add one
  336.      and one
  337.      sacl contr
  338. dont: out contr,pa5
  339.      lark ar0,7
  340. ntyt: lac tester,6
  341.      addh masko
  342.      sach yn0
  343.      out yn0,pa4   ; send wefax tone to the speaker
  344.  
  345. ;     end output
  346.  
  347. ;     Now begin demodulator
  348.      lack one
  349.      sacl modem  ; store control that makes complex tone
  350.      lack one  ;
  351.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  352.      sacl mpc  ;
  353.      lac phase
  354.      call tones ; go make complex tone
  355.      lac sine
  356.      sacl tester
  357.  
  358.      lt xn0  ; load the current sample
  359.      mpy cosine; multiply by cosine
  360.      pac
  361.      sach yn0,1 ; store it Q channel current sample
  362.      mpy sine ; multiply sample by sine
  363.      pac
  364.      sach xn0,1 ; now store it in current sample place for I channel
  365.      
  366. ;     Low pass for each sample cutoff is at 400 Hz. >1000Hz is 30+ db down
  367. ;     Roll off is smooth between 400 and 1000.
  368.  
  369. ;     First lowpass I arm product
  370.  
  371.      zac
  372. ;
  373.      lt xn23
  374.      mpyk -717
  375. ;
  376.      ltd xn22
  377.      mpyk -214
  378. ;
  379.      ltd xn21
  380.      mpyk -337
  381. ;
  382.      ltd xn20
  383.      mpyk -903
  384. ;
  385.      ltd xn19
  386.      mpyk -865
  387. ;
  388.      ltd xn18
  389.      mpyk -57
  390. ;
  391.      ltd xn17
  392.      mpyk -1356
  393. ;
  394.      ltd xn16
  395.      mpyk -1855
  396. ;
  397.      ltd xn15
  398.      mpyk -479
  399. ;
  400.      ltd xn14
  401.      mpyk 2845
  402. ;
  403.      ltd xn13
  404.      mpy h10
  405. ;
  406.      ltd xn12
  407.      mpy h11
  408. ;
  409.      ltd xn11
  410.      mpy h11
  411. ;
  412.      ltd xn10
  413.      mpy h10
  414. ;
  415.      ltd xn9
  416.      mpyk 2845
  417. ;
  418.      ltd xn8
  419.      mpyk -479
  420. ;
  421.      ltd xn7
  422.      mpyk -1855
  423. ;
  424.      ltd xn6
  425.      mpyk -1356
  426. ;
  427.      ltd xn5
  428.      mpyk -57
  429. ;
  430.      ltd xn4
  431.      mpyk 865
  432. ;
  433.      ltd xn3
  434.      mpyk 903
  435. ;
  436.      ltd xn2
  437.      mpyk 337
  438. ;
  439.      ltd xn1
  440.      mpyk -214
  441. ;
  442.      ltd xn0
  443.      mpyk -717
  444. ;
  445.      apac
  446. ;
  447.      sach xn0,1
  448.      
  449. ;  Now do the Q arm
  450. ;
  451.  
  452.      zac
  453. ;
  454.      lt yn23
  455.      mpyk -717
  456. ;
  457.      ltd yn22
  458.      mpyk -214
  459. ;
  460.      ltd yn21
  461.      mpyk -337
  462. ;
  463.      ltd yn20
  464.      mpyk -903
  465. ;
  466.      ltd yn19
  467.      mpyk -865
  468. ;
  469.      ltd yn18
  470.      mpyk -57
  471. ;
  472.      ltd yn17
  473.      mpyk -1356
  474. ;
  475.      ltd yn16
  476.      mpyk -1855
  477. ;
  478.      ltd yn15
  479.      mpyk -479
  480. ;
  481.      ltd yn14
  482.      mpyk 2845
  483. ;
  484.      ltd yn13
  485.      mpy h10
  486. ;
  487.      ltd yn12
  488.      mpy h11
  489. ;
  490.      ltd yn11
  491.      mpy h11
  492. ;
  493.      ltd yn10
  494.      mpy h10
  495. ;
  496.      ltd yn9
  497.      mpyk 2845
  498. ;
  499.      ltd yn8
  500.      mpyk -479
  501. ;
  502.      ltd yn7
  503.      mpyk -1855
  504. ;
  505.      ltd yn6
  506.      mpyk -1356
  507. ;
  508.      ltd yn5
  509.      mpyk -57
  510. ;
  511.      ltd yn4
  512.      mpyk 865
  513. ;
  514.      ltd yn3
  515.      mpyk 903
  516. ;
  517.      ltd yn2
  518.      mpyk 337
  519. ;
  520.      ltd yn1
  521.      mpyk -214
  522. ;
  523.      ltd yn0
  524.      mpyk -717
  525. ;
  526.      apac
  527. ;
  528.      sach yn0,1
  529. ;  Okay we now have filtered products with data bauding pseudo base banded
  530. ;  Let's close the loop and lock on
  531.      lac xn0;  Hard limit data line for phase error detector
  532.      bgez pdps  ; is data baud a plus one ?
  533.      lt yn0     ; get ready for a multiply
  534.      mpyk -1    ; multiply phase error arm by -1
  535.      pac
  536.      b ny       ; go close the loop
  537. pdps: lac yn0
  538. ny:  sacl c0   ; store sign corrected phase error.
  539.  
  540. ; error updates are computed compute new phase and freq
  541.  
  542.      lac c0,13 ; make phase gain 1/8 of phase error
  543.      sach cosy ;
  544.      lac cosy  ;
  545.      bgez delph  ; is phase error nonnegative?
  546.      add one,15  ;  No so bring it back from -angle to between 0 & 2*PI
  547. delph: add phase   ; add the old phase 
  548.      add freq    ; add the phase increment (frequency)
  549.      and mask    ; modulo 2*pi
  550.      sacl phase  ; store it for next sample complex tone generation step
  551.      lac xn0
  552.      bgz posd
  553.      lt mone
  554.      mpy xn0
  555.      pac
  556. posd: sacl data
  557.      b wait         ; go output and then do it again
  558.  
  559. ;     complex tone generator if modem>0 if modem<0 sine wave generator
  560.  
  561. tones: sacl wkph  ;  store a working copy
  562.      lac wkph,4
  563.      subh one
  564.      blz getem  ;  is it in a quadrant bigger than first?
  565.      subh one
  566.      bgez thfr; is it in a quadrant greater than two?
  567.      lac 1,13  ;  nope so load pi
  568.      sub wkph  ;  subtract phase so that it maps back into 1st quad
  569.      sacl wkph ; store
  570.      lac mone  ; load -1
  571.      sacl mpc  ; store it in the cosine multiplier
  572.      b getem   ; go read tables
  573. thfr: lac mone  ; multiplier for bottom half
  574.      sacl mps  ; store
  575.      lac wkph  ; 
  576.      sub one,13 ; map angle back to  upper half and go do it again
  577.      b tones
  578. getem: lac wkph,10 ; take 1st quadrant phase equiv for sine and pick 
  579.                    ; off coarse part of phase address
  580.      sach coph     ; store it
  581.      lack sintbl   ;  load sine table offset into accumulator
  582.      add coph      ; add coarse address off set
  583.      tblr sinx     ; read the coarse sine value
  584.      lac one,6     ;  load pi/2
  585.      sub coph      ; subtract the coarse phase to get cosines offset
  586.      sacl coph      
  587.      lack sintbl
  588.      add coph      ; do same as above for coarse cosine
  589.      tblr cosx
  590.      lac wkph      ; load working phase
  591.      and maskl     ;  mask off fine addres
  592.      sacl coph     ; store it
  593.      lack fines    ; locate fine table offset
  594.      add coph      ; add for offset into fine table
  595.      tblr siny     ;  read table
  596.      lack finec
  597.      add coph
  598.      tblr cosy
  599.      zac
  600.      lt sinx       ; load sinx
  601.      mpy cosy      ;  multiply by cosy
  602.      lta siny      ; load t reg with fine sin and accumulate previous prod.
  603.      mpy cosx      ; multiply by coarse cosx to use sin(X+Y)
  604.      apac          ; add the result to coarse sine
  605.      sach sine     ; store it.
  606.      lac modem 
  607.      blz mult
  608.      lac 1,12      ; load full address pi/2
  609.      sub wkph      ; subtract the working phase to get cosine
  610.      sacl wkph 
  611.      lac wkph,10   ;  from here to the later MARK it is identical to above
  612.      sach coph
  613.      lack sintbl
  614.      add coph
  615.      tblr sinx
  616.      lac one,6
  617.      sub coph
  618.      sacl coph
  619.      lack sintbl
  620.      add coph
  621.      tblr cosx
  622.      lac wkph
  623.      and maskl
  624.      sacl coph
  625.      lack fines
  626.      add coph
  627.      tblr siny
  628.      lack finec
  629.      add coph
  630.      tblr cosy
  631.      zac
  632.      lt cosy
  633.      mpy sinx
  634.      lta siny
  635.      mpy cosx
  636.      apac  ; MARK
  637.      sach cosine ; store it in the cosine
  638. mult: lt mps;  now we need to do a few multiplies by sign changes due to
  639.      mpy sine ; to quadrant part of phase address
  640.      pac;     multiply sine by sine sign (:-)  and
  641.      sacl sine ;  store the result
  642.      lac modem
  643.      bgz cosm
  644.      ret
  645. cosm: mpy cosine;  now multiply cosine by the same
  646.      pac
  647.      sacl cosine ; store it
  648.      lt mpc;  load cosine differentiator from sine sign (:-)
  649.      mpy cosine;  multiply
  650.      pac
  651.      sacl cosine ; store
  652.      ret
  653.      end
  654. ;  Ebbly Ebbly Ebbly thats all folks
  655.